home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
c
/
c_flow.zip
/
CFLOWX.C
< prev
next >
Wrap
Text File
|
1985-06-24
|
24KB
|
1,079 lines
/* CFLOWX.C: cflow cross-reference utility for function/macro calls
**
** Copyright (c) 1985 by:
**
** Lawrence R. Steeger
** 1009 North Jackson
** Milwaukee, Wisconsin 53202
** 414-277-8149
*/
#include <stdio.h> /* CI-C86 header */
#define VOID int
/* external functions */
extern VOID abort();
extern char *alloc();
extern VOID exit();
extern int fclose();
extern char *fgets();
extern FILE *fopen();
extern VOID fprintf();
extern VOID free();
extern char *lower();
extern VOID printf();
extern VOID qsort();
extern char *realloc();
extern VOID sprintf();
extern int sscanf();
extern char *strcat();
extern int strcmp();
extern char *strcpy();
extern int strlen();
extern int strncmp();
extern int tolower();
#include "cflowx.h" /* CFLOW/CFLOWX header */
#define VERSION 85
#define RELEASE 06
#define MODIFIC 20
#define outinfo(S) fputs(S, stdout)
outlogo()
{
fprintf(stdout, "\n%s V%02d.%02d.%02d - %s",
"CFLOWX",
VERSION, RELEASE, MODIFIC,
"cflow cross-reference generator");
outinfo("\nCopyright (c) 1985 by Lawrence R. Steeger\n");
}
outhelp()
{
outinfo("\nusage: cflowx [-[efimr]] infile [>outfile]");
outinfo("\n note: infile is created by the");
outinfo(" CFLOW utility using the -x flag\n");
outinfo("\nreports: -e function/macro external definition report");
outinfo("\n -f path\\file name report");
outinfo("\n -i function/macro internal definition report");
outinfo("\n -m macro name cross-reference report");
outinfo("\n -r function name cross-reference report");
outinfo("\n note: The order of the specified [efimr] flags will");
outinfo("\n be the order that the reports will generated in.");
}
#define OUTHDR 0 /* start output header */
#define OUTUPD 1 /* update output array */
#define OUTFLSH 2 /* flush output line */
#define OUTCLR 3 /* clear output line */
typedef struct _xref { /* cross-reference record */
struct _xref *_related; /* related XREF chain */
unsigned char _dup; /* duplicate entry flag */
int _fnmbr, /* file name number */
_level, /* {...} nest level number */
_line; /* line number */
unsigned int _str; /* record data string offset */
} XREF;
static XREF *xref = NULL, /* XREF element pointers */
*xref1 = NULL,
*xref2 = NULL,
*xref3 = NULL,
*xref4 = NULL,
*xchain = NULL;
/* useability macros for XREF */
#define related xref->_related
#define dup xref->_dup
#define fnmbr xref->_fnmbr
#define level xref->_level
#define line xref->_line
#define str xref->_str
#define related1 xref1->_related
#define dup1 xref1->_dup
#define fnmbr1 xref1->_fnmbr
#define level1 xref1->_level
#define line1 xref1->_line
#define str1 xref1->_str
#define related2 xref2->_related
#define dup2 xref2->_dup
#define fnmbr2 xref2->_fnmbr
#define level2 xref2->_level
#define line2 xref2->_line
#define str2 xref2->_str
#define related3 xref3->_related
#define dup3 xref3->_dup
#define fnmbr3 xref3->_fnmbr
#define level3 xref3->_level
#define line3 xref3->_line
#define str3 xref3->_str
#define related4 xref4->_related
#define dup4 xref4->_dup
#define fnmbr4 xref4->_fnmbr
#define level4 xref4->_level
#define line4 xref4->_line
#define str4 xref4->_str
#define relxc xchain->_related
#define dupxc xchain->_dup
#define fnmbrxc xchain->_fnmbr
#define levelxc xchain->_level
#define linexc xchain->_line
#define strxc xchain->_str
typedef struct _rqueue { /* xref record queue header */
XREF **__xref; /* XREF record queue pointer */
unsigned char _sorted; /* sorted queue flag */
unsigned int _total, /* offset counter */
_index; /* offset index */
} RQUEUE;
static RQUEUE rqueue[HIGHKEY]; /* xref record queue headers */
static int rkey = 0, /* xref record queue keys */
rkey1 = 0,
rkey2 = 0;
/* useability macros for RQUEUE */
#define pxref rqueue[rkey].__xref
#define sorted rqueue[rkey]._sorted
#define total rqueue[rkey]._total
#define index rqueue[rkey]._index
#define pxref1 rqueue[rkey1].__xref
#define sorted1 rqueue[rkey1]._sorted
#define total1 rqueue[rkey1]._total
#define index1 rqueue[rkey1]._index
#define pxref2 rqueue[rkey2].__xref
#define sorted2 rqueue[rkey2]._sorted
#define total2 rqueue[rkey2]._total
#define index2 rqueue[rkey2]._index
static unsigned char *strings = NULL; /* character strings buffer */
static unsigned int stringl = 0; /* character strings length */
static char *invrec = /* standard input error format */
"invalid record %s- %d: \"%s";
static int reportc = 0; /* report function counter */
static PFI *(reports) = NULL; /* report function pointers */
/* mainline */
main(argc, argv)
int argc;
unsigned char **argv;
{
int i, j;
outlogo(); /* display utility logo */
if (argc < 2) { /* too few arguments */
outhelp();
exit(1); /* exit abnormal */
}
for (rkey = 0; rkey < HIGHKEY; rkey++) { /* reset queue headers */
pxref = NULL;
sorted = FALSE;
total = 0;
index = 0;
}
for (i = 1; i < argc; i++) { /* process -flags */
if (*argv[i] == '-') {
flags(argv[i]);
for (j = i--, --argc; j < argc; j++)
argv[j] = argv[j+1];
}
}
if (argc < 2) { /* no filename specified ! */
outhelp();
exit(1); /* exit abnormal */
}
buildq(argv[1]); /* build CFLOWX record queues */
dupfile(); /* detect duplicate files */
for (i = 0; i < reportc; i++) /* generate CFLOWX reports */
(*(reports[i]))();
exit(0); /* exit normal */
}
/* process command line flags */
flags(flag)
unsigned char *flag;
{
int i;
PFI function;
int reporte(), /* function/macro external */
reportf(), /* path\file name */
reporti(), /* function/macro internal */
reportm(), /* macro cross_reference */
reportr(); /* function cross_reference */
for (i = 0; flag[++i];) { /* scan all characters */
function = NULL;
switch (tolower(flag[i])) { /* set any valid flag */
case 'e': /* function/macro external */
function = reporte;
break;
case 'f': /* path\file name */
function = reportf;
break;
case 'i': /* function/macro internal */
function = reporti;
break;
case 'm': /* macro cross_reference */
function = reportm;
break;
case 'r': /* function cross_reference */
function = reportr;
break;
default:
abort("Unknown flag: '%c'\n", flag[i]);
break;
}
if (function != NULL) {
reports = realloc(reports, (sizeof(PFI)*(reportc+1)));
if (reports == NULL)
abort("REALLOC - reports");
reports[reportc++] = function;
}
}
flag[0] = EOS; /* terminate flag */
}
/* build CFLOWX record queues */
buildq(filename)
unsigned char *filename;
{
unsigned char *cp,
string[MAXBUF];
unsigned int stradd(); /* add string to char buffer */
int currec, /* current input record */
crelxkey, /* current related base key */
i,
j;
FILE *fptr; /* input file pointer */
XREF *crelated; /* related XREF base pointer */
if ((fptr = fopen(filename, "r+")) == NULL) /* open input file */
abort("FOPEN - %s\n", filename);
currec = 0; /* start record counter */
crelated = NULL; /* clear related chain base */
while (1) { /* scan XREF input */
if (fgets(string,MAXBUF,fptr)==FALSE) /* get record */
break;
xref = alloc(sizeof(XREF)); /* next XREF element */
++currec; /* update line count */
/* scan for standard fields */
if ((i=sscanf(string,
cxref((MAXFLDS-1)),
&rkey,
&fnmbr,
&level,
&line)
) != ((MAXFLDS-1)*2)) {
printf("sscanf(%d)\n", i);
abort(invrec, "sscanf ", currec, string);
}
if (rkey >= HIGHKEY) /* validate record key */
abort(invrec, "type ", currec, string);
/* skip over standard fields */
for (i=j=0; j != (MAXFLDS-1) && string[i] != RS; i++)
if (string[i] == U